/*
 * @Descripttion:
 * @version:
 * @Author: zhaomangang
 * @Date: 2024-06-25 17:32:47
 * @LastEditors: zhaomangang
 * @LastEditTime: 2024-06-25 18:33:01
 */

#include "../include/recognition_baidu.h"
#include "../include/common.h"
#include <QObject>
#include <QMap>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QEventLoop>

RecognitionBaiDu::RecognitionBaiDu()
{
    baidu_token_url_ = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%1&client_secret=%2&";
    baidu_speech_url_ = "https://vop.baidu.com/server_api?dev_pid=1537&cuid=%1&token=%2";
    client_id_ = "uORPpqxmT9jlAbEshHy0ubTg";
    client_secret_ = "VuE3zv7aK0oCKgzhvtXC4bBZbHT4CLMT";
    access_token_ = "";

    getAccessToken();
}

RecognitionBaiDu::~RecognitionBaiDu()
{
}

bool RecognitionBaiDu::post_sync(QString url, QMap<QString, QString> header, QByteArray requestData, QByteArray &replyData)
{
    //    发送请求的对象
    QNetworkAccessManager manager;
    //    请求 对象
    QNetworkRequest request;
    request.setUrl(url);
    QMapIterator<QString, QString> it(header);
    while (it.hasNext())
    {
        it.next();
        request.setRawHeader(it.key().toLatin1(), it.value().toLatin1());
    }
    // 设置openssl签名配置,否则在ARM上会报错
    QSslConfiguration conf = request.sslConfiguration();
    conf.setPeerVerifyMode(QSslSocket::VerifyNone);
// #if (QT_VERSION > QT_VERSION_CHECK(5, 0, 0))
//     conf.setProtocol(QSsl::TlsV1_0);
// #else
//     conf.setProtocol(QSsl::TlsV1);
// #endif
    conf.setProtocol(QSsl::AnyProtocol);
    request.setSslConfiguration(conf);

    QNetworkReply *reply = manager.post(request, requestData);
    QEventLoop l;
    // 一旦服务器返回，reply会发出信号
    connect(reply, &QNetworkReply::finished, &l, &QEventLoop::quit);
    l.exec();
    if (reply != nullptr && reply->error() == QNetworkReply::NoError)
    {

        replyData = reply->readAll();
        return true;
    }
    else
    {
        RB_DEBUG << "request error!" << reply->error();
        return false;
    }
}

void RecognitionBaiDu::getAccessToken()
{
    QString token_url = QString(baidu_token_url_).arg(client_id_).arg(client_secret_);
    QMap<QString, QString> header;
    header.insert(QString("Content-Type"), QString("audio/pcm;rate=16000"));
    QByteArray request_data; // 请求内容
    QByteArray reply_data;   // url返回内容
    bool result = post_sync(token_url, header, request_data, reply_data);
    if (result)
    {
        access_token_ = getJsonValue(reply_data, "access_token");
        RB_DEBUG << "access_token: " << access_token_;
    }
    else
    {
        RB_DEBUG << "get access_token error!";
    }
}

QString RecognitionBaiDu::speechIdentify(QString fileName)
{
    //语音识别
    QByteArray reply_data;
    QString speech_url = QString(baidu_speech_url_).arg(QHostInfo::localHostName()).arg(access_token_);
    QFile file;
    file.setFileName(fileName);
    file.open(QIODevice::ReadOnly);
    QByteArray request_data;
    request_data = file.readAll();
    file.close();
    QMap<QString, QString> header;
    header.insert(QString("Content-Type"), QString("audio/pcm;rate=16000"));
    //再次发起请求
    bool result = post_sync(speech_url, header, request_data, reply_data);
    if (result)
    {
        QString ret_text = getJsonValue(reply_data, "result");
        RB_DEBUG << "ret_text: " << ret_text;
        return ret_text;
    }
    else
    {
        RB_DEBUG << "speechIdentify error!";
        return "";
    }
}

QString RecognitionBaiDu::getJsonValue(QByteArray ba, QString key)
{
    QJsonParseError parseError;
    QJsonDocument jsondocument = QJsonDocument::fromJson(ba, &parseError);
    if (parseError.error == QJsonParseError::NoError)
    {
        if (jsondocument.isObject())
        {
            QJsonObject jsonObject = jsondocument.object();
            if (jsonObject.contains(key))
            {
                QJsonValue jsonvalue = jsonObject.value(key);
                if (jsonvalue.isString())
                    return jsonvalue.toString();
                else if (jsonvalue.isArray())
                {
                    QJsonArray arr = jsonvalue.toArray();
                    QJsonValue val = arr.at(0);
                    return val.toString();
                }
            }
        }
    }
    return "";
}
